package com.ruoyi.datastatistics.service.impl;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ruoyi.basedata.domain.UsersXb;
import com.ruoyi.basedata.domain.vo.UserTerminalsRequestVO;
import com.ruoyi.basedata.domain.vo.UserTerminalsVO;
import com.ruoyi.basedata.mapper.UsersXbMapper;
import com.ruoyi.basedata.service.IElectricityAreaLineService;
import com.ruoyi.basedata.service.IElectricityAreaReportService;
import com.ruoyi.basedata.service.IUserTerminalsxbJoinService;
import com.ruoyi.basedata.service.IUsersXbService;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.datastatistics.domain.*;
import com.ruoyi.datastatistics.mapper.ElectricityMeterHistoryDataMapper;
import com.ruoyi.datastatistics.mapper.MeterHistoryDataMapper;
import com.ruoyi.datastatistics.service.*;
import com.ruoyi.system.mapper.SysDictDataMapper;
import com.ruoyi.system.service.ISysDictDataService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.datastatistics.mapper.BillMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
/**
 * 欠费明细Service业务层处理
 *
 * @author zt
 * @date 2025-05-27
 */
@Service
public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements IBillService
{
    @Autowired
    private BillMapper billMapper;

    @Autowired
    private UsersXbMapper usersXbMapper;

    @Autowired
    private ITerminalsFreezeXbService terminalsFreezeXbService;

    @Autowired
    private IElectricityTerminalsFreezeXbService electricityTerminalsFreezeXbService;

    @Autowired
    private IPublicShareComsumeReportService publicShareComsumeReportService;
    @Autowired
    private IPublicShareReportService publicShareReportService;
    @Autowired
    private IBillService billService;
    @Autowired
    private IBillDetailService billDetailService;

    @Autowired
    private IUserTerminalsxbJoinService userTerminalsxbJoinService;

    @Autowired
    private IPublicShareUserJoinService publicShareUserJoinService;

    @Autowired
    private IUsersXbService usersXbService;
    @Autowired
    private ElectricityMeterHistoryDataMapper electricityMeterHistoryDataMapper;
    @Autowired
    private MeterHistoryDataMapper meterHistoryDataMapper;
    @Autowired
    private IElectricityRealtimegatherdataXbService electricityRealtimegatherdataXbService;
    @Autowired
    private IRealtimegatherdataXbService realtimegatherdataXbService;

    @Autowired
    private SysDictDataMapper dictDataMapper;

    @Autowired
    private IElectricityAreaReportService electricityAreaReportServiceImpl;
    @Autowired
    private IElectricityAreaLineService electricityAreaLineService;

    @Autowired
    private IDataService dataService;

    /**
     * 查询欠费明细
     *
     * @param id 欠费明细主键
     * @return 欠费明细
     */
    @Override
    public Bill selectBillById(Long id)
    {

        return billMapper.selectById(id);
    }

    /**
     * 查询欠费明细列表
     *
     * @param bill 欠费明细
     * @return 欠费明细
     */
    @Override
    public List<Bill> selectBillList(Bill bill)
    {
        return billMapper.selectBillList(bill);
    }

    @Override
    public List<BillBo> selectBillListStat(Bill bill) {
        List<String> readDateList = Arrays.stream(bill.getReadDate().split(",")).collect(Collectors.toList());
        bill.setReadDateList(readDateList);
        List<BillBo> billBoList = billMapper.selectBillListStat(bill);
        return billBoList;
    }

    /**
     * 新增欠费明细
     *
     * @param bill 欠费明细
     * @return 结果
     */
    @Override
    public int insertBill(Bill bill)
    {
        return billMapper.insert(bill);
    }

    /**
     * 新增开账总报表
     * @param date
     * @return
     */
    @Override
    public int insertBill(String date,String userId)
    {
        return billMapper.insertForDate(date,userId);
    }

    /**
     * 修改欠费明细
     *
     * @param bill 欠费明细
     * @return 结果
     */
    @Override
    public int updateBill(Bill bill)
    {
        bill.setUpdateTime(DateUtils.getNowDate());
        return billMapper.updateById(bill);
    }

    /**
     * 批量删除欠费明细
     *
     * @param ids 需要删除的欠费明细主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteBillByIds(Long[] ids)
    {
        return billMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除欠费明细信息
     *
     * @param id 欠费明细主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteBillById(Long id)
    {
        return billMapper.deleteById(id);
    }

    @Transactional
    @Override
    public void updateBillByIds(Long[] ids)
    {
        List<Bill> list = new ArrayList<>();
        for (Long id : ids){
            Bill bill = new Bill();
            bill.setId(id);
            bill.setUpdateTime(DateUtils.getNowDate());
            bill.setStatus(1);
            list.add(bill);
        }
        this.updateBatchById(list);
    }

    @Override
    public List<Bill> getBillList(String userId, Integer checkFlg) {
        return billMapper.selectList(new LambdaQueryWrapper<Bill>().eq(Bill::getUserId, userId).eq(Bill::getStatus, checkFlg)
                .orderByDesc(Bill::getReadDate).orderByAsc(Bill::getUsageType));
    }



    /**
     * 验证某个用户是否满足某个开账
     * @param userId
     * @param departureTime
     * @return
     */
    @Override
    public Map<String, Object>  checkBillForUser(String userId, String departureTime){
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("userWaterTerminalListForNoH", null);
        resMap.put("userElectricityTerminalListForNoH", null);
        List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType("day");
        int day = dictDatas.size()>0 ?Integer.parseInt(dictDatas.get(0).getDictValue()) : 1;
        //查找该用户离场时，所有相关的水表设备在某段时间内没有读数的
        List<UserTerminalsVO> list_userWaterTerminal = usersXbMapper.getUserWaterTerminalListForNoH(userId,departureTime,day);
       // List<UserTerminalsVO> list_otherWaterTerminal = usersXbMapper.getOtherWaterTerminalListForNoH(userId,departureTime,1);
        //查找该用户离场时，所有相关的电表设备在某段时间内没有读数的
        List<UserTerminalsVO> list_userElectricityTerminal = usersXbMapper.getUserElectricityTerminalListForNoH(userId,departureTime,day);
       // List<UserTerminalsVO> list_otherElectricityTerminal = usersXbMapper.getOtherElectricityTerminalListForNoH(userId,departureTime,1);

        resMap.put("userWaterTerminalListForNoH", list_userWaterTerminal);
        resMap.put("userElectricityTerminalListForNoH", list_userElectricityTerminal);

        return resMap;
    }
    /**
     * 验证某个用户是否满足某个开账
     * @param userId
     * @param departureTime
     * @return
     */
    @Override
    public Map<String, Object>  checkBillForOther(String userId, String departureTime){
        Map<String, Object> resMap = new HashMap<>();

        resMap.put("otherWaterTerminalListForNoH", null);
        resMap.put("otherElectricityTerminalListForNoH", null);
        List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType("day");
        int day = dictDatas.size()>0 ?Integer.parseInt(dictDatas.get(0).getDictValue()) : 1;
        //查找该用户离场时，所有相关的水表设备在某段时间内没有读数的
      //  List<UserTerminalsVO> list_userWaterTerminal = usersXbMapper.getUserWaterTerminalListForNoH(userId,departureTime,1);
        List<UserTerminalsVO> list_otherWaterTerminal = usersXbMapper.getOtherWaterTerminalListForNoH(userId,departureTime,day);
        //查找该用户离场时，所有相关的电表设备在某段时间内没有读数的
       // List<UserTerminalsVO> list_userElectricityTerminal = usersXbMapper.getUserElectricityTerminalListForNoH(userId,departureTime,1);
        List<UserTerminalsVO> list_otherElectricityTerminal = usersXbMapper.getOtherElectricityTerminalListForNoH(userId,departureTime,day);

        resMap.put("otherWaterTerminalListForNoH", list_otherWaterTerminal);
        resMap.put("otherElectricityTerminalListForNoH", list_otherElectricityTerminal);
        return resMap;
    }
    /**
     * 用户离场开账    @Transactional
     * @param userId
     * @param departureTime
     * @return
     */
//
    @Override
    public int insertBillForUseLeve(String userId, String departureTime){
        usersXbService.updateUserForLeveOnDepartureTime(userId,departureTime);
        //生成设备用量
        int i = terminalsFreezeXbService.insertTerminalsFreezeXbForPhase("2", departureTime.substring(0,7), userId,departureTime);
        int i_1 = electricityTerminalsFreezeXbService.insertElectricityTerminalsFreezeXbForPhase("2", departureTime.substring(0,7), userId,departureTime);

        if( i>0 || i_1>0){
            terminalsFreezeXbService.insertTerminalsFreezeXbForPhase("3", departureTime.substring(0,7), userId,departureTime);
            electricityTerminalsFreezeXbService.insertElectricityTerminalsFreezeXbForPhase("3", departureTime.substring(0,7), userId,departureTime);
        }
        //生成用户用量
        if( i>0 || i_1>0){
            i = billDetailService.insertBillDetailForElectricityTerminals("2",departureTime.substring(0,10),departureTime.substring(0,7),userId);//String frequencyType, String freezeTime, Integer userId
            billDetailService.insertBillDetailForElectricityTerminals("3",departureTime.substring(0,10),departureTime,userId);//String frequencyType, String freezeTime, Integer userId
            i_1 = billDetailService.insertBillDetailForWaterTerminals("2",departureTime.substring(0,10),departureTime.substring(0,7),userId);//String frequencyType, String freezeTime, Integer userId
            billDetailService.insertBillDetailForWaterTerminals("3",departureTime.substring(0,10),departureTime,userId);//String frequencyType, String freezeTime, Integer userId

        }
        //生成公摊生产报表
        if( i>0 || i_1>0){
            i = publicShareReportService.insertPublicShareReportForWaterTerminals("3",departureTime.substring(0,10),departureTime,userId);
            i_1 = publicShareReportService.insertPublicShareReportForElectricityTerminals("3",departureTime.substring(0,10),departureTime,userId);
        }
        //生成公摊消费用户报表
        if( i>0 || i_1>0){
            i =publicShareComsumeReportService.insertPublicShareComsumeReportForWaterTerminals("2",departureTime, userId);
            i_1 =publicShareComsumeReportService.insertPublicShareComsumeReportForElectricityTerminals("2",departureTime, userId);
        }
        //生成开账报表
        if( i>0 || i_1>0){
            billService.insertBill(departureTime.substring(0,7),userId);
        }

        userTerminalsxbJoinService.deleteUserTerminalsxbJoinByUser(userId);
        publicShareUserJoinService.deletePublicShareUserJoinByUser(userId);
        usersXbService.updateUserForLeveOnUserMark(userId);
        return 1;

    }

    /**
     * 生成用户用量报表
     * @param freezeTime
     * @return
     */
    @Transactional
    @Override
    public  int insertUserDosageReportForMonth(String freezeTime){
        //生成设备上月用量
        int i = terminalsFreezeXbService.insertTerminalsFreezeXbForAll("month", freezeTime);
        int i_1 = electricityTerminalsFreezeXbService.insertElectricityTerminalsFreezeXbForAll("month", freezeTime);

        //生成用户用量
        if( i>0 || i_1>0){
            i = billDetailService.insertBillDetailForElectricityTerminals("1",freezeTime,freezeTime,"");//String frequencyType, String freezeTime, Integer userId
            i_1 = billDetailService.insertBillDetailForWaterTerminals("1",freezeTime,freezeTime,"");//String frequencyType, String freezeTime, Integer userId
        }
        return 1;
    }
    /**
     * 月报表生成
     * @param freezeTime
     * @return
     */
    @Transactional
    @Override
    public int insertBillForMonth(String freezeTime){
        //String yesterday = com.ruoyi.common.utils.DateUtil.getNMonthForamt(1,"yyyy-MM");


        //生成公摊生产报表
        int i = publicShareReportService.insertPublicShareReportForWaterTerminals("1",freezeTime,freezeTime,"");
        int i_1 = publicShareReportService.insertPublicShareReportForElectricityTerminals("1",freezeTime,freezeTime,"");

        //生成公摊消费用户报表
        if( i>0 || i_1>0){
            i =publicShareComsumeReportService.insertPublicShareComsumeReportForWaterTerminals("1",freezeTime,"");
            i_1 =publicShareComsumeReportService.insertPublicShareComsumeReportForElectricityTerminals("1",freezeTime,"");
        }
        //生成开账报表
        if( i>0 || i_1>0){
            billService.insertBill(freezeTime,"");
        }

        try{
            //能耗报表-用水-日报表
            electricityAreaReportServiceImpl.insertElectricityAreaReportForAll("2","0","month",freezeTime);
            //能耗报表-用电-日报表
            electricityAreaReportServiceImpl.insertElectricityAreaReportForAll("1","0","month",freezeTime);
            //能耗分项报表-用水-日报表
            electricityAreaReportServiceImpl.insertElectricityAreaReportForAll("2","1","month",freezeTime);
            //能耗分项报表-用电-日报表
            electricityAreaReportServiceImpl.insertElectricityAreaReportForAll("1","1","month",freezeTime);
            //线损报表-日报表
            electricityAreaLineService.insertElectricityAreaLineForAll("month",freezeTime);

        }catch (Exception e){

        }
        return 1;

    }

    /**
     * 用户日报表生成机制
     * @param freezeTime
     * @return
     */
    @Transactional
    @Override
    public int insertBillForDay(String freezeTime) {
        //String yesterday = com.ruoyi.common.utils.DateUtil.getDayDate(-1);
        //用水报表-日报表
        terminalsFreezeXbService.insertTerminalsFreezeXbForAll("day",freezeTime);
        //用电报表-日报表
        electricityTerminalsFreezeXbService.insertElectricityTerminalsFreezeXbForAll("day",freezeTime);
        //用户日报表
        billDetailService.insertBillDetailOneDayForElectricityTerminals(freezeTime);
        billDetailService.insertBillDetailOneDayForWaterTerminals(freezeTime);
        return 1;
    }
    /**
     * 弃用
     * @param requestVO
     * @return
     */
    @Override
    public int dealUserLeaveForinsertHistoryData(UserTerminalsRequestVO requestVO) {
        String userId = requestVO.getUserId();
        //离场用户信息
        List<UserTerminalsVO> userElectricityTerminalList = requestVO.getUserElectricityTerminalListForNoH();
        //离场用户关联公摊其他用户信息
        List<UserTerminalsVO> userWaterTerminalList = requestVO.getUserWaterTerminalListForNoH();
        //离场用户信息
        List<UserTerminalsVO> otherElectricityTerminalList = requestVO.getOtherElectricityTerminalListForNoH();
        List<UserTerminalsVO> otherWaterTerminalList = requestVO.getOtherWaterTerminalListForNoH();
        //手动抄表数据录入到历史表和实时表中
        String userdepartureTime = requestVO.getUserdepartureTime();
        userdepartureTime = "".equals(userdepartureTime) || null == userdepartureTime ? DateUtils.getTime() :userdepartureTime;
        for(UserTerminalsVO vo : userElectricityTerminalList){
            //insertMeterHistoryDataAndRealData(vo,requestVO.getUserdepartureTime());
            insertMeterHistoryDataAndRealData(vo,userdepartureTime);
        }
        for(UserTerminalsVO vo : userWaterTerminalList){
           // insertMeterHistoryDataAndRealData(vo,requestVO.getUserdepartureTime());
            insertMeterHistoryDataAndRealData(vo,userdepartureTime);
        }
        if(otherElectricityTerminalList !=null){
            for(UserTerminalsVO vo : otherElectricityTerminalList){
                // insertMeterHistoryDataAndRealData(vo,requestVO.getUserdepartureTime());
                if(vo.getTotalFlow() != null)
                    insertMeterHistoryDataAndRealData(vo,userdepartureTime);
            }
        }
       if(otherWaterTerminalList != null){
           for(UserTerminalsVO vo : otherWaterTerminalList){
               // insertMeterHistoryDataAndRealData(vo,requestVO.getUserdepartureTime());
               if(vo.getTotalFlow() != null)
                   insertMeterHistoryDataAndRealData(vo,userdepartureTime);
           }
       }

        return 1;
    }


    /**
     * @Description: 插入电数据
     * @date: 2025/10/15 09:52
     * @author: kyx
     */

    public void insertMeterHistoryDataAndRealData(UserTerminalsVO userTerminalsVO,String userdepartureTime)
    {
        Integer energyType = userTerminalsVO.getEnergyType();
        if(energyType == 1){
            ElectricityMeterHistoryData meterHistoryData = new ElectricityMeterHistoryData();
            meterHistoryData.setTenantId(userTerminalsVO.getTenantId());
            meterHistoryData.setUserId(userTerminalsVO.getUserId());
            meterHistoryData.setTerminalId(userTerminalsVO.getTerminalId());
            meterHistoryData.setLocationNb(userTerminalsVO.getLocationNb());
            meterHistoryData.setCombinationActiveEnergy1(userTerminalsVO.getTotalFlow());
            meterHistoryData.setReadDate(DateUtils.parseDate(userdepartureTime));
            //属性转换
            ElectricityRealtimegatherdataXb electricityRealtimegatherdataXb = new ElectricityRealtimegatherdataXb();
            BeanUtils.copyProperties(meterHistoryData,electricityRealtimegatherdataXb);
            electricityMeterHistoryDataMapper.insert(meterHistoryData);
            //删除实时数据存在的数据
            electricityRealtimegatherdataXbService.getBaseMapper().delete(new LambdaQueryWrapper<ElectricityRealtimegatherdataXb>()
                    .eq(ElectricityRealtimegatherdataXb::getLocationNb,meterHistoryData.getLocationNb()));
            //插入新的实时数据
            electricityRealtimegatherdataXbService.insertRealtimegatherdataXb(electricityRealtimegatherdataXb);
        } else if (energyType == 2) {
            MeterHistoryData meterHistoryData = new MeterHistoryData();
            meterHistoryData.setTenantId(userTerminalsVO.getTenantId());
            meterHistoryData.setUserId(userTerminalsVO.getUserId());
            meterHistoryData.setTerminalId(userTerminalsVO.getTerminalId());
            meterHistoryData.setLocationNb(userTerminalsVO.getLocationNb());
            meterHistoryData.setTotalFlow(userTerminalsVO.getTotalFlow());
            meterHistoryData.setReadNumber(userTerminalsVO.getReadNumber());
            meterHistoryData.setReverseNumber(userTerminalsVO.getReverseNumber());
            meterHistoryData.setReadDate(userdepartureTime);

            //属性转换
            RealtimegatherdataXb realtimegatherdataXb = new RealtimegatherdataXb();
            BeanUtils.copyProperties(meterHistoryData,realtimegatherdataXb);
            realtimegatherdataXb.setReadDate(DateUtils.parseDate(meterHistoryData.getReadDate()));
            meterHistoryDataMapper.insert(meterHistoryData);
            //删除实时数据存在的数据
            realtimegatherdataXbService.getBaseMapper().delete(new LambdaQueryWrapper<RealtimegatherdataXb>()
                    .eq(RealtimegatherdataXb::getLocationNb,meterHistoryData.getLocationNb()));
            //插入新的实时数据
            realtimegatherdataXbService.insertRealtimegatherdataXb(realtimegatherdataXb);
        }
    }

    /**
     * 同步水表实时数据
     * @param terminalIds
     * @param checkoutDate
     * @return
     */
    @Override
    public int  synchronizationWaterData(List<String> terminalIds, LocalDateTime checkoutDate){
        boolean flag =  dataService.saveRealLastDataWater(terminalIds,checkoutDate);
        return flag? 1: 0;
    }

    /**
     * 同步电表实时数据
     * @param terminalIds
     * @param checkoutDate
     * @return
     */
    @Override
    public int  synchronizationEletricityData(List<String> terminalIds, LocalDateTime checkoutDate){
        boolean flag =  dataService.saveRealLastDataEletricity(terminalIds,checkoutDate);
        return flag? 1: 0;
    }
}
